home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / hard / drivr / spartan34_4.lha / true_SCSI_version / mydev.asm < prev    next >
Assembly Source File  |  1980-07-31  |  19KB  |  844 lines

  1. ;
  2. ;
  3. ; Concurrent copy bug fixed version
  4. ; 31 May, 1992 TM
  5. ; 17 Jun, 1992 TM
  6. ; 15 Sep, 1992 TM GENERIC version
  7. ; 05 Oct, 1992 HL SCSI_Direct implemented
  8. ; 22 Oct, 1992 HL SCSI_Direct SendIO() bug fixed
  9. ; 25 Oct, 1992 HL SCSI_Direct does now return scsi_Status
  10. ;
  11.    SECTION   section
  12.  
  13.    NOLIST
  14.    include "exec/types.i"
  15.    include "exec/nodes.i"
  16.    include "exec/lists.i"
  17.    include "exec/libraries.i"
  18.    include "exec/devices.i"
  19.    include "exec/io.i"
  20.    include "exec/alerts.i"
  21.    include "exec/initializers.i"
  22.    include "exec/memory.i"
  23.    include "exec/resident.i"
  24.    include "exec/ables.i"
  25.    include "exec/errors.i"
  26.    include "exec/tasks.i"
  27.    include "devices/scsidisk.i"
  28.    include   'libraries/expansion.i'
  29.    include 'libraries/configvars.i'
  30.    include 'libraries/configregs.i'
  31.  
  32.    include "asmsupp.i"
  33.    include "mydev.i"
  34.    include "scsi.i"
  35.  
  36.    LIST
  37.  
  38.    XREF   SCSIRdWt
  39.    XREF   SCSIDirectCmd
  40.  
  41.    ;------ These don't have to be external, but it helps some
  42.    ;------ debuggers to have them globally visible
  43.    XDEF   Init
  44.    XDEF   Open
  45.    XDEF   Close
  46.    XDEF   Expunge
  47.    XDEF   Null
  48.    XDEF   myName
  49.    XDEF   BeginIO
  50.    XDEF   AbortIO
  51.  
  52.    XLIB   AddIntServer
  53.    XLIB   RemIntServer
  54.    XLIB   Debug
  55.    XLIB   InitStruct
  56.    XLIB   InitCode
  57.    XLIB   OpenLibrary
  58.    XLIB   CloseLibrary
  59.    XLIB   Alert
  60.    XLIB   FreeMem
  61.    XLIB   Remove
  62.    XLIB   AllocMem
  63.    XLIB   AddTask
  64.    XLIB   RemTask
  65.    XLIB   ReplyMsg
  66.    XLIB   Signal
  67.    XLIB   GetMsg
  68.    XLIB   PutMsg
  69.    XLIB   Wait
  70.    XLIB   WaitPort
  71.    XLIB   AllocSignal
  72.    XLIB   SetTaskPri
  73.    XLIB   GetCurrentBinding   ; Get list of boards for this driver
  74.    XLIB   MakeDosNode
  75.    XLIB   AddDosNode
  76.    XLIB   Permit
  77.    XLIB   Forbid
  78.  
  79.    INT_ABLES
  80.  
  81. FirstAddress:
  82.    CLEAR   d0
  83.    rts
  84.  
  85.  
  86. MYPRI   EQU   10
  87.  
  88. initDDescrip:
  89.                ;STRUCTURE RT,0
  90.      DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
  91.      DC.L    initDDescrip      ; APTR  RT_MATCHTAG
  92.      DC.L    EndCode      ; APTR  RT_ENDSKIP
  93.      DC.B    RTF_AUTOINIT      ; UBYTE RT_FLAGS
  94.      DC.B    VERSION      ; UBYTE RT_VERSION
  95.      DC.B    NT_DEVICE      ; UBYTE RT_TYPE
  96.      DC.B    MYPRI         ; BYTE  RT_PRI
  97.      DC.L    myName      ; APTR  RT_NAME
  98.      DC.L    idString      ; APTR  RT_IDSTRING
  99.      DC.L    Init         ; APTR  RT_INIT
  100.                ; LABEL RT_SIZE
  101.  
  102.  
  103. subSysName:
  104. myName:      MYDEVNAME
  105.  
  106. dosName:   DOSNAME
  107.  
  108.    ; a major version number.
  109. VERSION:   EQU   34
  110.  
  111. REVISION:   EQU   4
  112.  
  113. idString:   dc.b   'Spartan 34.4-TM1.1G/HL1.1b (non adaptec) (31 OCT 92)',13,10,0
  114.  
  115.    ; force word allignment
  116.    ds.w   0
  117.  
  118. Init:
  119.    DC.L   MyDev_Sizeof      ; data space size
  120.    DC.L   funcTable      ; pointer to function initializers
  121.    DC.L   dataTable      ; pointer to data initializers
  122.    DC.L   initRoutine      ; routine to run
  123.  
  124.  
  125. funcTable:
  126.  
  127.    ;------ standard system routines
  128.    dc.l   Open
  129.    dc.l   Close
  130.    dc.l   Expunge
  131.    dc.l   Null
  132.  
  133.    ;------ my device definitions
  134.    dc.l   BeginIO
  135.    dc.l   AbortIO
  136.  
  137.    ;------ function table end marker
  138.    dc.l   -1
  139.  
  140.  
  141. dataTable:
  142.    INITBYTE   LH_TYPE,NT_DEVICE
  143.    INITLONG   LN_NAME,myName
  144.    INITBYTE   LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
  145.    INITWORD   LIB_VERSION,VERSION
  146.    INITWORD   LIB_REVISION,REVISION
  147.    INITLONG   LIB_IDSTRING,idString
  148.    DC.L   0
  149.  
  150.  
  151. initRoutine:
  152.    movem.l   d0-d1/a0-a1/a3-a5,-(sp)   ; Preserve ALL modified registers
  153.    move.l   d0,a5
  154.  
  155.    ;------ save a pointer to exec
  156.    move.l   a6,md_SysLib(a5)
  157.  
  158.    ;------ save a pointer to our loaded code
  159.    move.l   a0,md_SegList(a5)
  160.  
  161.    lea.l   dosName,A1      ; Get expansion lib. name
  162.    moveq   #0,D0
  163.    CALLSYS   OpenLibrary      ; Open the expansion library
  164.    move.l   d0,md_DosLib(a5)
  165.    bne.s   init_end
  166.    ALERT   AG_OpenLib!AO_DOSLib
  167. ;   bra   init_error
  168.  
  169. initDosOK:
  170. ;   lea.l   ExLibName,a1
  171. ;   moveq   #0,d0
  172. ;   CALLSYS   OpenLibrary
  173. ;   move.l   d0,a3
  174. ;   bne   init_OpSuccess
  175. ;   ALERT   AG_OpenLib!AO_ExpansionLib
  176. ;   bra   init_error
  177.  
  178. init_OpSuccess:
  179. ;   move.b   #$80,NCR+2   ;Resets SCSI bus
  180. ;   move.l   #0,a0
  181. ;   move.l   #$3ec,d0
  182. ;   move.b   #$0,NCR+2    ;Clear Chip for I/O
  183. ;   moveq   #$e,d1
  184. ;   move.l   a6,-(a7)
  185. ;   move.l   a3,a6
  186. ;   CALLSYS   InitCode
  187. ;   move.l   (a7)+,a6
  188. ;   move.l   d0,a4
  189. ;   move.l   $20(a4),d0
  190. ;   tst.l   d0
  191. ;   beq   init_error
  192. ;   move.l   d0,md_Base(a5)
  193. ;   bra   init_end
  194. init_error:
  195.    moveq   #0,d0
  196. init_end:
  197.    movem.l   (sp)+,d0-d1/a0-a1/a3-a5
  198.    rts
  199.  
  200.  
  201. Open:      ; ( device:a6, iob:a1, unitnum:d0, flags:d1 )
  202.    movem.l   d2/a2-a4,-(sp)
  203.    move.l   a1,a2      ; save the iob
  204.  
  205.    ;------ see if the unit number is in range
  206.    ;move.l   #1,d0
  207.    ;subq.w   #1,d0
  208.    cmp.l   #MD_NUMUNITS,d0
  209.    bcc.s   Open_Error   ; unit number out of range
  210.  
  211.    ;------ see if the unit is already initialized
  212.    move.l   d0,d2      ; save unit number
  213.    lsl.l   #2,d0
  214.    lea.l   md_Units(a6,d0.l),a4
  215.    move.l   (a4),d0
  216.    bne.s   Open_UnitOK
  217.  
  218.    ;------ try and conjure up a unit
  219.    bsr   InitUnit
  220.  
  221.    ;------ see if it initialized OK
  222.    move.l   (a4),d0
  223.    beq.s   Open_Error
  224.  
  225. Open_UnitOK:
  226.    move.l   d0,a3      ; unit pointer in a3
  227.  
  228.    move.l   d0,IO_UNIT(a2)
  229.  
  230.    ;------ mark us as having another opener
  231.    addq.w   #1,LIB_OPENCNT(a6)
  232.    addq.w   #1,UNIT_OPENCNT(a3)
  233.    ;------ prevent delayed expunges
  234.    bclr   #LIBB_DELEXP,md_Flags(a6)
  235.    moveq.l   #0,d0
  236.  
  237. Open_End:
  238.    movem.l   (sp)+,d2/a2-a4
  239.    rts
  240.  
  241. Open_Error:
  242.    movem.l   d0,-(sp)
  243. looop2:   move.l   #1,d0
  244.    cmp.b   #0,d0
  245.    bne   looop2
  246.    movem.l   (sp)+,d0
  247.  
  248.    move.b   #IOERR_OPENFAIL,IO_ERROR(a2)
  249.    bra.s   Open_End
  250.  
  251.  
  252. Close:      ; ( device:a6, iob:a1 )
  253. ;   movem.l   d1/a2-a3,-(sp)
  254. ;
  255. ;   move.l   a1,a2
  256. ;
  257. ;   move.l   IO_UNIT(a2),a3
  258. ;
  259.    ;------ make sure the iob is not used again
  260. ;   moveq.l   #-1,d0
  261. ;   move.l   d0,IO_UNIT(a2)
  262. ;   move.l   d0,IO_DEVICE(a2)
  263. ;
  264.    ;------ see if the unit is still in use
  265. ;   subq.w   #1,UNIT_OPENCNT(a3)
  266.  
  267. ;   bne.s   Close_Device
  268. ;   bsr   ExpungeUnit
  269.  
  270. Close_Device:
  271.    ;------ mark us as having one fewer openers
  272. ;   moveq.l   #0,d0
  273. ;   subq.w   #1,LIB_OPENCNT(a6)
  274.  
  275.    ;------ see if there is anyone left with us open
  276. ;   bne.s   Close_End
  277.  
  278.    ;------ see if we have a delayed expunge pending
  279. ;   btst   #LIBB_DELEXP,md_Flags(a6)
  280. ;   beq.s   Close_End
  281.  
  282.    ;------ do the expunge
  283. ;   bsr   Expunge
  284.  
  285. Close_End:
  286. ;   movem.l   (sp)+,d1/a2-a3
  287. ;   rts
  288.  
  289.  
  290. Expunge:   ; ( device: a6 )
  291.  
  292. ;   movem.l   d1/d2/a5/a6,-(sp)   ; Best to save ALL modified registers
  293. ;   move.l   a6,a5
  294. ;   move.l   md_SysLib(a5),a6
  295.    
  296.    ;------ see if anyone has us open
  297.  ;  tst.w   LIB_OPENCNT(a5)
  298.  ;  beq   1$
  299.  
  300.    ;------ it is still open.  set the delayed expunge flag
  301. ;   bset   #LIBB_DELEXP,md_Flags(a5)
  302. ;   CLEAR   d0
  303. ;   bra.s   Expunge_End
  304.  
  305. 1$:
  306.    ;------ go ahead and get rid of us.  Store our seglist in d2
  307. ;   move.l   md_SegList(a5),d2
  308.  
  309.    ;------ unlink from device list
  310. ;   move.l   a5,a1
  311. ;   CALLSYS   Remove
  312. ;   move.l   md_DosLib(a5),a1
  313. ;   CALLSYS   CloseLibrary
  314.    
  315.    ;
  316.    ; device specific closings here...
  317.    ;
  318.  
  319.    ;------ free our memory
  320. ;   CLEAR   d0
  321. ;   CLEAR   d1
  322. ;   move.l   a5,a1
  323. ;   move.w   LIB_NEGSIZE(a5),d1
  324.  
  325. ;   sub.w   d1,a1
  326. ;   add.w   LIB_POSSIZE(a5),d0
  327. ;   add.l   d1,d0
  328.  
  329. ;   CALLSYS   FreeMem
  330.  
  331.    ;------ set up our return value
  332. ;   move.l   d2,d0
  333.  
  334. Expunge_End:
  335. ;   movem.l   (sp)+,d1/d2/a5/a6
  336. ;   rts
  337.  
  338.  
  339. Null:
  340.    CLEAR   d0
  341.    rts
  342.  
  343.  
  344. InitUnit:   ; ( d2:unit number, a3:scratch, a6:devptr )
  345.  
  346.    movem.l   d2-d4/a2,-(sp)
  347.  
  348.    ;------ allocate unit memory
  349.    move.l   #MyDevUnit_Sizeof,d0
  350.    move.l   #MEMF_PUBLIC!MEMF_CLEAR,d1
  351.    LINKSYS   AllocMem,md_SysLib(a6)
  352.  
  353.    tst.l   d0
  354.    beq   InitUnit_End
  355.  
  356.    move.l   d0,a3
  357.    move.b   d2,mdu_UnitNum(a3)   ; initialize unit number
  358.    move.l   a6,mdu_Device(a3)   ; initialize device pointer
  359.  
  360.  
  361.    ;------ Initialize the stack information
  362.    lea   mdu_stack(a3),a0   ; Low end of stack
  363.    move.l   a0,mdu_tcb+TC_SPLOWER(a3)
  364.    lea   MYPROCSTACKSIZE(a0),a0   ; High end of stack
  365.    move.l   a0,mdu_tcb+TC_SPUPPER(a3)
  366.    move.l   a3,-(A0)      ; argument -- unit ptr
  367.    move.l   a0,mdu_tcb+TC_SPREG(a3)
  368.    ;------ initialize the unit's list
  369.    lea   MP_MSGLIST(a3),a0
  370.    NEWLIST   a0
  371.    lea   mdu_tcb(a3),a0
  372.    move.l   a0,MP_SIGTASK(a3)
  373.    moveq.l   #0,d0         ; Don't need to re-zero it
  374.    move.l   a3,a2         ; InitStruct is initializing the UNIT
  375.    lea.l   mdu_Init,A1
  376.    LINKSYS   InitStruct,md_SysLib(a6)
  377.  
  378.    move.l   a3,mdu_is+IS_DATA(a3)   ; Pass int. server unit addr.
  379.  
  380. ;   Startup the task
  381.    lea   mdu_tcb(a3),a1
  382.    lea   Proc_Begin(PC),a2
  383.    move.l   a3,-(sp)      ; Preserve UNIT pointer
  384.    lea   -1,a3         ; generate address error
  385.                ; if task ever "returns"
  386.    CLEAR   d0
  387.    LINKSYS AddTask,md_SysLib(a6)
  388.    move.l   (sp)+,a3      ; restore UNIT pointer
  389.  
  390.    ;------ mark us as ready to go
  391.    move.l   d2,d0         ; unit number
  392.    lsl.l   #2,d0
  393.    move.l   a3,md_Units(a6,d0.l)   ; set unit table
  394.  
  395.  
  396. InitUnit_End:
  397.    movem.l   (sp)+,d2-d4/a2
  398.    rts
  399.    ;------ got an error.  free the unit structure that we allocated.
  400. InitUnit_FreeUnit:
  401.    bsr   FreeUnit
  402.    bra.s   InitUnit_End
  403.  
  404. FreeUnit:   ; ( a3:unitptr, a6:deviceptr )
  405.    move.l   a3,a1
  406.    move.l   #MyDevUnit_Sizeof,d0
  407.    LINKSYS   FreeMem,md_SysLib(a6)
  408.    rts
  409.  
  410.  
  411. ExpungeUnit:   ; ( a3:unitptr, a6:deviceptr )
  412.  ;  move.l   d2,-(sp)
  413.  
  414.  
  415.  ;  lea   mdu_tcb(a3),a1
  416.  ;  LINKSYS   RemTask,md_SysLib(a6)
  417.  
  418.    ;------ save the unit number
  419.  ;  CLEAR   d2
  420.  ;  move.b   mdu_UnitNum(a3),d2
  421.  
  422.    ;------ free the unit structure.
  423.  ;  bsr   FreeUnit
  424.  
  425.    ;------ clear out the unit vector in the device
  426.  ;  lsl.l   #2,d2
  427.  ;  clr.l   md_Units(a6,d2.l)
  428.  
  429.  ;  move.l   (sp)+,d2
  430.  
  431.    rts
  432.  
  433. cmdtable:
  434.    DC.L   Invalid      ; $00000001
  435.    DC.L   MyReset      ; $00000002
  436.    DC.L   RdWt      ; $00000004   Common routine for read/write
  437.    DC.L   RdWt      ; $00000008
  438.    DC.L   Update      ; $00000010
  439.    DC.L   Clear      ; $00000020
  440.    DC.L   MyStop      ; $00000040
  441.    DC.L   Start      ; $00000080
  442.    DC.L   Flush      ; $00000100
  443.    DC.L   Motor      ; $00000200  motor   (NO-OP)
  444.    DC.L   Seek      ; $00000400  seek   (NO-OP)
  445.    DC.L   Format      ; $00000800  format -> WRITE for harddisk
  446.    DC.L   MyRemove   ; $00001000  remove      (NO-OP)
  447.    DC.L   ChangeNum   ; $00002000  changenum      (Returns 0)
  448.    DC.L   ChangeState   ; $00004000  changestate   (Returns 0)
  449.    DC.L   ProtStatus   ; $00008000  protstatus      (Returns 0)
  450.    DC.L   RawRead      ; Not supported   (INVALID)
  451.    DC.L   RawWrite   ; Not supported   (INVALID)
  452.    DC.L   GetDriveType   ; Get drive type   (Returns 1)
  453.    DC.L   GetNumTracks   ; Get number of tracks (Returns NUMTRKS)
  454.    DC.L   AddChangeInt   ; Add disk change interrupt (NO-OP)
  455.    DC.L   RemChangeInt   ; Remove disk change interrupt ( NO-OP)
  456.    DC.L   Invalid      
  457.    DC.L   Invalid      
  458.    DC.L   Invalid     
  459.    DC.L   Invalid   
  460.    DC.L   Invalid  
  461.    DC.L   Invalid 
  462.    DC.L   SCSIDirect   
  463. cmdtable_end:
  464.  
  465. ; this define is used to tell which commands should not be queued
  466. ; command zero is bit zero.
  467. ; The immediate commands are Invalid, Reset, Stop, Start, Flush
  468. IMMEDIATES    EQU    $000001c3
  469.  
  470. ; These commands can NEVER be done "immediately" if using interrupts,
  471. ; since they would "wait" for the interrupt forever!
  472. ; Read, Write, Format
  473. NEVERIMMED    EQU    $0000080C
  474. ;
  475. ; BeginIO starts all incoming io.  The IO is either queued up for the
  476. ; unit task or processed immediately.
  477. ;
  478.  
  479. BeginIO:    ; ( iob: a1, device:a6 )
  480.     movem.l    d0/d1/a0/a3,-(sp)
  481.  
  482.     ;------ bookkeeping
  483.     move.l    IO_UNIT(a1),a3
  484.  
  485.     ;------ see if the io command is within range
  486.     move.w    IO_COMMAND(a1),d0
  487.     cmp.w    #MYDEV_END,d0
  488.     bcc    BeginIO_NoCmd
  489.         cmp.w   #4,d0
  490.         beq     BeginIO_NoCmd   ;filter UPDATE
  491.         cmp.w   #9,d0
  492.         beq     BeginIO_NoCmd   ;filter MOTOR
  493.     DISABLE    a0
  494.  
  495.     ;------ process all immediate commands no matter what
  496.     move.w    #IMMEDIATES,d1
  497.     btst    d0,d1
  498.     bne.s    BeginIO_Immediate
  499. ;
  500. ; !!! These lines are enabled so that all read/write requests would be
  501. ;     queued. TM  (A cure for the concurrent copy bug)
  502. ;
  503. ;    IFD    INTRRUPT    ; if using interrupts, ;DEBUG
  504.     ;------ queue all NEVERIMMED commands no matter what
  505.     move.w    #NEVERIMMED,d1
  506.     btst    d0,d1
  507.     bne.s    BeginIO_QueueMsg
  508. ;    ENDC
  509.  
  510.     ;------ see if the unit is STOPPED.  If so, queue the msg.
  511.     btst    #MDUB_STOPPED,UNIT_FLAGS(a3)
  512.     bne.s    BeginIO_QueueMsg
  513.  
  514.     ;------ this is not an immediate command.  see if the device is
  515.     ;------ busy.
  516.     bset    #UNITB_ACTIVE,UNIT_FLAGS(a3)
  517.     beq.s    BeginIO_Immediate
  518.  
  519.     ;------ we need to queue the device.  mark us as needing
  520.     ;------ task attention.  Clear the quick flag
  521. BeginIO_QueueMsg:
  522.     BSET    #UNITB_INTASK,UNIT_FLAGS(a3)
  523.     bclr    #IOB_QUICK,IO_FLAGS(a1)
  524.  
  525.     ENABLE    a0
  526.     move.l    a3,a0
  527.     LINKSYS    PutMsg,md_SysLib(a6)
  528.     bra    BeginIO_End
  529.  
  530. BeginIO_Immediate:
  531.     ENABLE    a0
  532.  
  533.     bsr    PerformIO
  534.  
  535. BeginIO_End:
  536.     movem.l    (sp)+,d0/d1/a0/a3
  537.     rts
  538.  
  539. BeginIO_NoCmd:
  540.     move.b    #IOERR_NOCMD,IO_ERROR(a1)
  541.     bra.s    BeginIO_End
  542.  
  543.  
  544. ;
  545. ; PerformIO actually dispatches an io request.  It expects a3 to already
  546. ; have the unit pointer in it.  a6 has the device pointer (as always).
  547. ; a1 has the io request.  Bounds checking has already been done on
  548. ; the io request.
  549. ;
  550.  
  551. PerformIO:    ; ( iob:a1, unitptr:a3, devptr:a6 )
  552.     move.l    a2,-(sp)
  553.     move.l    a1,a2
  554.  
  555.     clr.b    IO_ERROR(a2)        ; No error so far
  556.     move.w    IO_COMMAND(a2),d0
  557.     lsl    #2,d0            ; Multiply by 4 to get table offset
  558.     lea    cmdtable(pc),a0
  559.     move.l    0(a0,d0.w),a0
  560.  
  561.     jsr    (a0)
  562.  
  563.     move.l    (sp)+,a2
  564.     rts
  565.  
  566. ;
  567. ; TermIO sends the IO request back to the user.  It knows not to mark
  568. ; the device as inactive if this was an immediate request or if the
  569. ; request was started from the server task.
  570. ;
  571.  
  572. TermIO:        ; ( iob:a1, unitptr:a3, devptr:a6 )
  573.     move.w    IO_COMMAND(a1),d0
  574.     move.w    #IMMEDIATES,d1
  575.     btst    d0,d1
  576.     bne.s    TermIO_Immediate
  577.  
  578.     ;------ we may need to turn the active bit off.
  579.     btst    #UNITB_INTASK,UNIT_FLAGS(a3)
  580.     bne.s    TermIO_Immediate
  581.  
  582.     ;------ the task does not have more work to do
  583.     bclr    #UNITB_ACTIVE,UNIT_FLAGS(a3)
  584. TermIO_Immediate:
  585.     ;------ if the quick bit is still set then we don't need to reply
  586.     ;------ msg -- just return to the user.
  587.     btst    #IOB_QUICK,IO_FLAGS(a1)
  588.     bne.s    TermIO_End
  589.  
  590.     LINKSYS    ReplyMsg,md_SysLib(a6)
  591.  
  592. TermIO_End:
  593.     rts
  594.     
  595. SCSIDirect:
  596. ;    move.b    #HFERR_BadStatus,IO_ERROR(a1) ; HL Only if not supported
  597. ;       bsr   TermIO
  598. ;    rts
  599.    movem.l a2-a3/a4/a6/d2/d7,-(sp)
  600.    movem.l a6,-(sp)
  601.    move.l   IO_DATA(a1),a6
  602.    clr.l    IO_ACTUAL(a1)
  603.    clr.l    scsi_Actual(a6)      ; Initially, no data moved
  604.    move.l   scsi_Data(a6),a0
  605.    move.l   scsi_Length(a6),d0
  606.    move.l   scsi_Command(a6),a2
  607.  
  608.    move.l   IO_UNIT(a1),a3      ; Get unit pointer
  609.  
  610.    move.l   d0,scsi_Actual(a6)
  611.    CLEAR    d2
  612.    move.b   mdu_UnitNum(a3),d2
  613.  
  614.    jsr   SCSIDirectCmd
  615.  
  616.    move.b   d0,IO_ERROR(a1)
  617.    move.b   d7,scsi_Status(a6)
  618.    movem.l  (sp)+,a6
  619.    bsr   TermIO
  620.    movem.l (sp)+,a2-a3/a4/a6/d2/d7
  621.    rts
  622.  
  623. AbortIO: 
  624. RawRead:      ; 10 Not supported   (INVALID)
  625. RawWrite:      ; 11 Not supported   (INVALID)
  626. Invalid:
  627. GetNumTracks:
  628.    move.b   #IOERR_NOCMD,IO_ERROR(a1)
  629.    bsr   TermIO
  630.    rts
  631.  
  632. MyReset:
  633. AddChangeInt:
  634. RemChangeInt:
  635. MyRemove:
  636. Seek:
  637. Motor:
  638. Remove:
  639. ChangeNum:
  640. ChangeState:
  641. ProtStatus:
  642.    clr.l   IO_ACTUAL(a1)   ; Indicate drive isn't protected
  643.    bsr   TermIO
  644.    rts
  645.  
  646. GetDriveType:
  647.    move.l   #1,IO_ACTUAL(a1)      ; Make it look like 3.5"
  648.    bsr   TermIO
  649.    rts
  650.  
  651. RdWt:
  652. Format:
  653.    movem.l a2-a3/a6/d2,-(sp)
  654.    clr.l   IO_ACTUAL(a1)      ; Initially, no data moved
  655.    move.l   IO_DATA(a1),a0
  656.    move.l   IO_LENGTH(a1),d0
  657.  
  658.    ;------ deal with zero length I/O
  659.    beq.s   RdWt_end
  660.  
  661.  
  662.    move.l   IO_UNIT(a1),a3      ; Get unit pointer
  663.    move.l   a1,a2
  664.  
  665. *      check operation for legality
  666.  
  667.    move.l   IO_OFFSET(a2),d1
  668.    move.l   d1,d2
  669.    and.l   #$1ff,d2
  670.    bne   Sec_Error
  671.  
  672.  
  673.    move.l   d0,IO_ACTUAL(a2)
  674.    CLEAR    d2
  675.    move.b   mdu_UnitNum(a3),d2
  676.  
  677.    jsr   SCSIRdWt
  678.  
  679. RdWt_Clean:
  680.    move.b   d0,IO_ERROR(a1)
  681.    bra   RdWt_end
  682. Sec_Error:
  683.    move.b   #$fc,IO_ERROR(a1)
  684. RdWt_end:
  685.    bsr   TermIO
  686.    movem.l (sp)+,a2-a3/a6/d2
  687.    rts
  688.  
  689. Update:
  690. Clear:
  691.    bra   Invalid
  692.  
  693. MyStop:
  694.    bset   #MDUB_STOPPED,UNIT_FLAGS(a3)
  695.    bsr   TermIO
  696.    rts
  697.    
  698. Start:
  699.    bsr   InternalStart
  700.  
  701. ;   move.l   a2,a1            ; TM simul bug
  702.    bsr   TermIO
  703.  
  704.    rts
  705.  
  706. InternalStart:
  707.    ;------ turn processing back on
  708.     move.l    a1,-(sp)        ; TM simul bug -- save a1
  709.    bclr   #MDUB_STOPPED,UNIT_FLAGS(a3)
  710.  
  711.    ;------ kick the task to start it moving
  712. ;   move.l   a3,a1            ; TM simul bug
  713.    CLEAR   d0
  714. ;   move.l   MP_SIGBIT(a3),d1
  715.    move.b   MP_SIGBIT(a3),d1    ;TM
  716.    bset   d1,d0
  717.    LINKSYS   Signal,md_SysLib(a3)
  718.     move.l    (sp)+,a1        ; TM simul bug -- restore a1
  719.    rts
  720.  
  721.  
  722. Flush:
  723.    movem.l   d2/a1/a6,-(sp)        ; TM simul bug -- save a1
  724.  
  725.    move.l   md_SysLib(a6),a6
  726.  
  727.    bset   #MDUB_STOPPED,UNIT_FLAGS(a3)
  728.    sne   d2
  729.  
  730. Flush_Loop:
  731.    move.l   a3,a0
  732.    CALLSYS   GetMsg
  733.  
  734.    tst.l   d0
  735.    beq.s   Flush_End
  736.  
  737.    move.l   d0,a1
  738.    move.b   #IOERR_ABORTED,IO_ERROR(a1)
  739.    CALLSYS   ReplyMsg
  740.  
  741.    bra.s   Flush_Loop
  742.  
  743. Flush_End:
  744.  
  745.    move.l   d2,d0
  746.    movem.l   (sp)+,d2/a1/a6        ; TM simul bug
  747.  
  748.    tst.b   d0
  749.    beq.s   1$
  750.  
  751.    bsr   InternalStart
  752. 1$:
  753.  
  754. ;   move.l   a2,a1            ; TM simul bug
  755.    bsr   TermIO
  756.  
  757.    rts
  758.  
  759. ;   cnop   0,4         ; long word allign
  760.    DC.L   16         ; segment length -- any number will do
  761. myproc_seglist:
  762.    DC.L   0         ; pointer to next segment
  763.  
  764. ; the next instruction after the segment list is the first executable address
  765.  
  766. Proc_Begin:
  767.  
  768.    move.l   4,a6
  769.  
  770.    ;------ Grab the argument
  771.    move.l   4(sp),a3      ; Unit pointer
  772.  
  773.    move.l   mdu_Device(a3),a5   ; Point to device structure
  774.  
  775.  
  776.  
  777.    ;------ Allocate the right signal
  778.  
  779.    moveq   #-1,d0         ; -1 is any signal at all
  780.    CALLSYS   AllocSignal
  781.  
  782.    move.b   d0,MP_SIGBIT(a3)
  783.    move.b   #PA_SIGNAL,MP_FLAGS(a3)
  784.  
  785.    ;------ change the bit number into a mask, and save in d7
  786.  
  787.    moveq   #0,d7
  788.    bset   d0,d7
  789.  
  790.    bra.s   Proc_CheckStatus
  791.  
  792.    ;------ main loop: wait for a new message
  793. Proc_MainLoop:
  794.    move.l   d7,d0
  795.    CALLSYS   Wait
  796.  
  797. Proc_CheckStatus:
  798.    ;------ see if we are stopped
  799.    btst   #MDUB_STOPPED,UNIT_FLAGS(a3)
  800.    bne.s   Proc_MainLoop      ; device is stopped
  801.  
  802.    ;------ lock the device
  803.    bset   #UNITB_ACTIVE,UNIT_FLAGS(a3)
  804.    bne.s   Proc_MainLoop      ; device in use
  805.    ;------ get the next request
  806. Proc_NextMessage:
  807.    move.l   a3,a0
  808.    CALLSYS   GetMsg
  809.    tst.l   d0
  810.    beq.s   Proc_Unlock      ; no message?
  811.  
  812.    ;------ do this request
  813.    move.l   d0,a1
  814.    exg   a5,a6         ; put device ptr in right place
  815.    bsr   PerformIO
  816.    exg   a5,a6         ; get syslib back in a6
  817.  
  818.    bra.s   Proc_NextMessage
  819.  
  820.    ;------ no more messages.  back ourselves out.
  821. Proc_Unlock:
  822.    and.b   #$ff&(~(UNITF_ACTIVE!UNITF_INTASK)),UNIT_FLAGS(a3)
  823.    bra   Proc_MainLoop
  824. mdu_Init:
  825. ;   ------ Initialize the device
  826.  
  827.    INITBYTE   MP_FLAGS,PA_IGNORE
  828.    INITBYTE   LN_TYPE,NT_DEVICE
  829.    INITLONG   LN_NAME,myName
  830.    INITBYTE   mdu_Msg+LN_TYPE,NT_MSGPORT ;Unit starts with MsgPort
  831.    INITLONG   mdu_Msg+LN_NAME,myName      
  832.    INITLONG   mdu_tcb+LN_NAME,myName
  833.    INITBYTE   mdu_tcb+LN_TYPE,NT_TASK
  834.    INITBYTE   mdu_tcb+LN_PRI,MYPROCPRI
  835.    INITBYTE   mdu_is+LN_PRI,4      ; Int priority 4
  836.    IFD   INTRRUPT
  837.    INITLONG   mdu_is+IS_CODE,myintr   ; Interrupt routine addr
  838.    ENDC
  839.    INITLONG   mdu_is+LN_NAME,myName
  840.    DC.L   0
  841.  
  842. EndCode:
  843.     END            ;TM
  844.